#ifndef __COMMAND_MODE_H__
#define __COMMAND_MODE_H__

//#include <map>



_FK_BEGIN


//void virtual SetCommandName(BSTR *bstrName);
//virtual i_call execute(void);
//virtual v_call undo();
//void virtual Command_Describe(BSTR *bstrName);



typedef void* HCOMMAND;

typedef BOOL (WINAPI *LPFNCOMMANDEXECUTE)(HCOMMAND hCommand);
typedef BOOL (WINAPI *LPFNCOMMANDSTATE)(HCOMMAND hCommand);
typedef BOOL (WINAPI *LPFNCOMMANDUNDO)(HCOMMAND hCommand);
typedef BOOL (WINAPI *LPFNCOMMANDFREE)(HCOMMAND hCommand);

typedef struct tagCOMMANDDATA
{
	DWORD dwSize;
	LPFNCOMMANDEXECUTE pfnExcecute;
	LPFNCOMMANDSTATE pfnState;
	LPFNCOMMANDUNDO	pfnUndo;
	LPFNCOMMANDFREE pfnFree;
	LPARAM lParam;
}COMMANDDATA,*LPCOMMANDDATA;



HCOMMAND WINAPI FmCreateNullCommand(void);

HCOMMAND WINAPI FmF8SF57CD20(LPCOMMANDDATA lpCmdData);

BOOL WINAPI FmC9104Ad5dBDC49(HCOMMAND hcmd);

// FmCmdState
BOOL WINAPI FmCC3A354FC0(HCOMMAND hcmd);

// FmCmdUndo
BOOL WINAPI FmC8E3CE908661CFA133D(HCOMMAND hcmd);

// FmCmdExecute
BOOL WINAPI FmACB0437A134257BD(HCOMMAND hcmd);

// FmCmdGetParam
LPARAM WINAPI FmF2CE8828B5DB(HCOMMAND hcmd);

#define FmCreateCommand					FmF8SF57CD20
#define FmCmdClose						FmC9104Ad5dBDC49
#define FmCmdState						FmCC3A354FC0
#define FmCmdUndo						FmC8E3CE908661CFA133D
#define FmCmdExecute					FmACB0437A134257BD
#define FmCmdGetParam					FmF2CE8828B5DB

//
///*
// * Dialog Box Command IDs
// */
//#define IDOK                1
//#define IDCANCEL            2
//#define IDABORT             3
//#define IDRETRY             4
//#define IDIGNORE            5
//#define IDYES               6
//#define IDNO                7
//#if(WINVER >= 0x0400)
//#define IDCLOSE         8
//#define IDHELP          9
//#endif /* WINVER >= 0x0400 */
//
//#if(WINVER >= 0x0500)
//#define IDTRYAGAIN      10
//#define IDCONTINUE      11
//#endif /* WINVER >= 0x0500 */
//
//#if(WINVER >= 0x0501)
//#ifndef IDTIMEOUT
//#define IDTIMEOUT 32000
//#endif
//#endif /* WINVER >= 0x0501 */

#define IDCMD_ERROR    -1

class _FK_OUT_CLASS ICommand : public fk::LObject
{
	_FK_RTTI_;

private:

protected:

public:
	_FK_DBGCLASSINFO_

	ICommand(fk::LObject* powner);
	virtual ~ICommand(void);
	virtual void SetCommandName(BSTR *bstrName);
	virtual int execute(void)=0;
	virtual int ThreadRunExecute(QUICKNOTIFYPROC* pQuickNotify, LPARAM lParam);
	virtual BOOL QueryCommandEnadle();
	virtual void undo(void)=0;
};


class _FK_OUT_CLASS LCommands : public fk::LObject
{
private:
protected:
public:
	LCommands(fk::LObject* powner);
	virtual ~LCommands(void);

	virtual b_call add(fk::ICommand* pcmd) = 0;
	virtual v_call clear(void) = 0;
	virtual b_call remove(fk::ICommand* pcmd) = 0;
	virtual i_call GetCount(void) = 0;
	virtual fk::ICommand* GetItem(int iitem) = 0;
	virtual b_call GetDatas(void) = 0;
	virtual b_call GetEnumPlus(fk::LEnumData** ppEnumData) = 0;

	virtual b_call ExecuteFull(void) = 0;
	virtual b_call ExecuteTop(void) = 0;

	static fk::LCommands* _call NewCommands(fk::LObject* powner);
};




#define EVENT_COMMAND_DELETE		0x1

struct CommandEventDelete
{
	fk::NOTIFYEVENT nEvent;
	ICommand* pcmd;
	int iExecute;
	LPARAM lParam;
};


class LCommandInvoker
{
private:
	ICommand* m_pCommand;

public:
	LCommandInvoker(ICommand *pCommand=NULL)
	{
		m_pCommand=pCommand;
	}
	~LCommandInvoker()
	{
		Free();
	}
	void SetCommand( ICommand* p ) throw()
	{
		ATLASSUME( m_pCommand == NULL );
		m_pCommand=p;
	}
	HRESULT invoker()
	{
		if(m_pCommand!=NULL)
			return m_pCommand->execute();
		return S_FALSE;
	}
	void Free()
	{
		if(m_pCommand!=NULL)
		{
			delete m_pCommand;
			m_pCommand=NULL;
		}
	}
	ICommand* GetCommand()	{	return m_pCommand;	}
};


_FK_END

#endif // __COMMAND_MODE_H__
